Form validation is an important part of any app.
In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.
useForm()
The useForm()
function lets us create form context that we can use to create reactive forms.
To use it, we write:
<template>
<form @submit="onSubmit">
<Field name="email" />
<span>{{ errors.email }}</span>
<br />
<Field name="password" />
<span>{{ errors.password }}</span>
<br />
<input type="submit" />
</form>
</template>
<script>
import { Field, useForm } from "vee-validate";
import * as yup from "yup";
export default {
components: {
Field,
},
setup() {
const { handleSubmit, errors } = useForm({
validationSchema: yup.object().shape({
email: yup.string().required().email(),
password: yup.string().required().min(3),
}),
});
const onSubmit = handleSubmit((values, actions) => {
alert(JSON.stringify(values, null, 2));
actions.resetForm();
});
return {
errors,
onSubmit,
};
},
};
</script>
We call the useForm
function with the validationSchema
property to set the validation schema.
email
and password
are the name
attribute values of the fields.
It returns an object with the handleSubmit
function and the errors
object with the form validation errors.
We use errors
in the form.
And we call handleSubmit
with a callback to handle submissions.
values
has the inputted values.
actions
has the resetForm
method to reset the validation status of the form.
We can set the initial values of the form fields.
To do this, we write:
<template>
<form @submit="onSubmit">
<Field name="email" />
<span>{{ errors.email }}</span>
<br />
<Field name="password" />
<span>{{ errors.password }}</span>
<br />
<input type="submit" />
</form>
</template>
<script>
import { Field, useForm } from "vee-validate";
import * as yup from "yup";
export default {
components: {
Field,
},
setup() {
const { handleSubmit, errors } = useForm({
initialValues: {
email: "abc@abc.com",
password: "",
},
validationSchema: yup.object().shape({
email: yup.string().required().email(),
password: yup.string().required().min(3),
}),
});
const onSubmit = handleSubmit((values, actions) => {
alert(JSON.stringify(values, null, 2));
actions.resetForm();
});
return {
errors,
onSubmit,
};
},
};
</script>
to add the initialValues
property into the object we pass into useForm
to set the value of the email
field.
Dynamic Form
We can use Vee-Validate 4 to validate dynamically rendered forms.
For example, we can write:
<template>
<Form v-slot="{ errors }" :validation-schema="schema.validation">
<div v-for="field in schema.fields" :key="field.name">
<label :for="field.name">{{ field.label }}</label>
<Field :as="field.as" :id="field.name" :name="field.name" />
<span>{{ errors[field.name] }}</span>
</div>
<button>Submit</button>
</Form>
</template>
<script>
import { Form, Field } from "vee-validate";
import * as yup from "yup";
export default {
components: {
Form,
Field,
},
data() {
return {
schema: {
fields: [
{
label: "Name",
name: "name",
as: "input",
},
{
label: "Email",
name: "email",
as: "input",
},
{
label: "Password",
name: "password",
as: "input",
},
],
validation: yup.object().shape({
email: yup.string().email().required(),
name: yup.string().required(),
password: yup.string().min(8).required(),
}),
},
};
},
};
</script>
In the data
method, we return an object with the schema
reactive property.
It has the data to render the fields in the fields
array.
We use it to render the label and name and what to render the Field
as with the as
property.
The validation
property has the validation schema for our fields.
In the template, we render the items and display the errors in the span
.
This is more convenient than adding each field into our template.
Conclusion
We can create forms with the useForm
function.
And we can create dynamic forms with validation in our Vue 3 app with Vee-Validate 4.